package com.zhaungjie.base.utils.PropertiesCopyUtils.operation;

import com.zhaungjie.base.utils.LambdaStructureParser.LambdaStructureParser;
import com.zhaungjie.base.utils.ReflectionUtils;
import com.zhaungjie.base.utils.PropertiesCopyUtils.PropertiesCopyConfigRoot;

import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

public class AssociatedCopyOperation<S, T> {
    private PropertiesCopyConfigRoot<S, T> propertiesCopyConfigRoot;
    private LambdaStructureParser.NANRFunction<S> sourceSFunction;
    private LambdaStructureParser.NANRFunction<T> targetSFunction;

    public AssociatedCopyOperation(PropertiesCopyConfigRoot<S, T> propertiesCopyConfigRoot, LambdaStructureParser.NANRFunction<S> sourceSFunction, LambdaStructureParser.NANRFunction<T> targetSFunction) {
        this.propertiesCopyConfigRoot = propertiesCopyConfigRoot;
        this.sourceSFunction = sourceSFunction;
        this.targetSFunction = targetSFunction;
    }

    /**
     * 开始关联拷贝
     * @param sources
     * @param targets
     * @return
     */
    public List<T> copy(List<S> sources,List<T> targets) {
        if (sources == null || sources.isEmpty() || targets == null || targets.isEmpty()) return targets;
        String sourceKeyFieldName = LambdaStructureParser.convertToFieldName(sourceSFunction);
        String tagetKeyFieldName = LambdaStructureParser.convertToFieldName(targetSFunction);
        Map<Object,S> sourceMap;
        try {
            sourceMap = sources.stream().collect(Collectors.toMap(source-> ReflectionUtils.getFieldValue(source,sourceKeyFieldName), source->source));
        }catch(Exception e) {
            throw new RuntimeException("关联拷贝失败，请检查关联字段是否正确与重复，详细原因："+e.getMessage());
        }
        for (T target : targets) {
            Object key = ReflectionUtils.getFieldValue(target,tagetKeyFieldName);
            S source = sourceMap.get(key);
            if (source == null) continue;
            propertiesCopyConfigRoot.setTemplate(target).produce(source);
        }
        return targets;
    }


}